Repository navigation
fix(metadata-protocol)!: the read naming no package withholds a customization pair's row of a name every holder of which is disabled (ADR-0150 D3) - #33383
Conversation
…name only disabled packages hold Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
…ly disabled packages hold, both save and hydration orders Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
…a disabled package holds; spec: register the semantic entry Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
…, /layers, execution read) Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
📓 Docs Drift Check5 anchor(s) derived from 2 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 173 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin f7bdefc713dea6c3eeb812e11fd21a0bb16a1efc && git checkout f7bdefc713dea6c3eeb812e11fd21a0bb16a1efc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e0ce1b523c9cdb625211fc866593f57aee9223ee ada9d16be7d93fdf1e297b6483c120840e1d6f0a && git checkout -B drift-repro e0ce1b523c9cdb625211fc866593f57aee9223ee && git merge --no-ff ada9d16be7d93fdf1e297b6483c120840e1d6f0a
node scripts/docs-audit/affected-docs.mjs --json e0ce1b523c9cdb625211fc866593f57aee9223ee |
|
domain:server#5 · os-elon-musk · session_016WV4cy1y7UNVbT2QAdmgdn Request: review · area E1 · head 28c3513 · 2026-11-14T18:45Z Fixes #32814 (ADR-0150 D3: the read naming no package withholds a customization pair's row of a name every holder of which is disabled). |
|
Contract-review-claim: session_016WV4cwxS1ZpSu2hAMRcqbt · head 28c3513 · 2026-11-14T18:46Z review#1 (E1) takes this head. |
Contract reviewServed-tier: Face: schema (a ① Derived judgments
② Semver level
Ruling on ③ Boundary flags
④ Design judgment
Implemented-by: VERDICT: PASS |
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn
|
domain:server#5 · os-elon-musk · session_016WV4cy1y7UNVbT2QAdmgdn ACCEPT · area E1 · 2026-11-14T18:51Z
|
Contract reviewServed-tier: Delta of record 6882490650 (PASS on ① Derived judgments
② Semver levelUnchanged from record 6882490650: ③ Boundary flagsUnchanged. N1–N3 of record 6882490650 stand as nits. The author has the list-read residual (N1) in follow-up work together with #33401. ④ Design judgmentUnchanged: the PR's own changes are byte-identical by patch id, so record 6882490650's judgment of the semantic entry and Implemented-by: VERDICT: PASS |
Requested by Elon · project thread
Fixes #32814
Clause-②: no (narrowing)
Metadata-protocol: none
Skills-docs: none — no skill and no doc teaches what the read naming no package answers at a member only a customization pair stores (
skills/**andcontent/docs/**grepped for disabled packages: the hits are action and componentdisabledpredicates, package lifecycle references and a release page);content/docs/deployment/marketplace-handbook.mdxalready says a disabled module is hidden.维护者速读
welcome)的所有持有包都被停用、而某个语言成员(如fr-FR)只存在于 App 定制配对包(APP.custom)的存储行里时,不带?package=的裸读(GET /meta/TYPE/NAME?member=、/layers、执行读)现在答 404(停用持有者的“已隐藏”条目),以前会把那行配对定制返回出来。?package=APP.custom的精确读早已答 404,裸读却还漏出这一行。裸读以前只在“什么都没读到”时才判断持有者是否全部停用,读到配对行就直接返回了。packages/metadata-protocol/src/protocol-meta-item-face.ts的isHoldersPairRow与readMetaItemFace里withheldHolder的三元判断(风险 hunk:裸读分支新增的判定);packages/objectql/src/package-scoped-exact-qualifier.test.ts末尾的[#32814]组;packages/rest/src/meta-disabled-package-doors.test.ts末尾的[#32814]组。pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/package-scoped-exact-qualifier.test.ts -t 32814,预期 12 个全部通过:两种保存顺序 × 是否水合 × 模块/App 自身作持有者,裸读都答 404;重新启用后与两持有者 CONTROL 仍返回配对行。What changes
readMetaItemFace(@objectstack/metadata-protocol, the body behindgetMetaItemandgetMetaItemForExecution) judges whether every package holding the name is disabled (disabledOnlyHolderOf, #32183) only when the read reached nothing, or, on an exact read, when it reached a row not stored under the named package (epic ruling R4-B). On the read naming no package, a row it did reach was returned unjudged. For a bundled type such asemail_template, the member a customization pair adds (an App pair'sfr-FRrow beside a module's shippeden-US) is reached that way, so with the module disabled the bare read served the pair's row, while?package=APP.customat the same member already answered the withheld item (ruling R4-C,disabledExactAddressHolder).Now, on the read naming no package, a row stamped with a customization pair (
pairsOf) of a package holding the name (isHoldersPairRow) is judged the same way: when every holder is disabled, the answer is the holder's withheld item, the answer the same read gives with no row stored. A pair row is bound over the holders it is a pair of and is never a holder of its own (#32354 contract review N2, #32408), so it is withheld with them.fr-FRstored only underAPP.custom)maine540baf?member=fr-FRRESOURCE_NOT_FOUND(protocol: no item,packageId= the holder)/layers?member=fr-FR(RestServer)RESOURCE_NOT_FOUNDgetMetaItemForExecution)The other doors of the same name were measured but are outside this card: the list reads (
getMetaItems,getMetaItemsForExecution) still list the pair's row while every holder is disabled (protocol-meta-list-reads.ts, an E1 hot file this order may not edit; see Acceptance notes).Tests
packages/objectql/src/package-scoped-exact-qualifier.test.ts, new top-leveldescribe[#32814]at the end of the file (no overlap with the[#32561]block fix(metadata-protocol)!: an App pair row declared for a package that still ships the name is never served at a bundle addition's address (ADR-0150 D4) #33251 edits): 8 negative pins (module of the App / the App itself × row before / after the disable × hydrated or not) asserting no item,packageId= the holder, no byte of the pair's row, and no item on the execution face, each followed by a re-enable CONTROL; 2 pins that the answer with the pair's row stored equals the answer with none (the envelope'sversionleft out, see Acceptance notes); 2 CONTROLs (two modules of the App, both registration orders: one enabled serves the pair's row, both disabled withhold it).packages/rest/src/meta-disabled-package-doors.test.ts, new top-leveldescribe[#32814]at the end: the plain read and/layersat the member answer 404RESOURCE_NOT_FOUNDin both save orders, then the pair's row once re-enabled; CONTROL: no row stored answers the same 404.Acceptance notes
narrowed. Nothing an author can write is refused, re-shaped or changes meaning: the pair row is still accepted on save and served again on re-enable. Only what a read serves while every holder is disabled moves, the same classification fix(metadata-protocol)!: a name a disabled package holds through a stored row is judged over the served set, never by save order (ADR-0150 D3) #33130 (the served-set sibling) declared. The narrowing is carried byClause-②: no (narrowing), the BREAKING banner and the registered semantic entry.fr-FRrow is still served by the bare read (measured onmainand on this head).servedRowHolderOfdocuments that a name with a package-less row is "judged as before" (a customization of no one holder); whether it is the disabled holder's customization is not ruled, so it is reported, not guessed.getMetaItems/getMetaItemsForExecutionwith no package list the pair's row while every holder is disabled (measured onmaine540baf, both save orders). Reported for a separate card;protocol-meta-list-reads.tsis a hot file for this order.version. The protocol's withheld envelope keeps theversionof what the read reached on every withheld arm (a disabled holder's own stored row keeps its row's version, measured), so the no-row equality pin compares everything else. No door serves it: both REST doors answer 404./publishedtakes no member, and the bare read at the canonical member was already withheld onmain; not moved.Verification
Premise, on
origin/maine540baf (a probe over the same fixtures, not committed): with the only holder disabled, the bare read atfr-FRserved the pair's row in all four save/hydration orders, for a module of the App and for the App itself; with no row stored it answered the holder's withheld item. Every other probed state (holder enabled, two holders, a package outside the App, a package-less row, the holder's own row) answered the same on this head as onmain.Pins and ablation (one mutation: the bare-read arm of the new judgment replaced with a constant false)
pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/package-scoped-exact-qualifier.test.ts -t 32814:Tests 12 passed.scripts/ablation-replace.mjs, thenpnpm --filter @objectstack/metadata-protocol build,ablation-dist-preflight.mjsmarker present indist/index.jsanddist/index.cjs):Tests 10 failed | 2 passed— the 8 withheld pins and the 2 no-row equality pins red, the 2 two-module CONTROLs green.git diff HEADempty, rebuilt, preflight--absentand whole-tree clean):Tests 12 passed.pnpm --filter @objectstack/rest exec vitest run --maxWorkers=2 src/meta-disabled-package-doors.test.ts:Tests 44 passed (44). Ablated:-t 32814Tests 2 failed | 1 passed(both save orders red, the no-row CONTROL green). Restored:Tests 3 passed.Local gates and type checks (head 28c3513, after merging origin/main 199e362)
pnpm --filter @objectstack/metadata-protocol typecheck,@objectstack/objectql typecheck,@objectstack/rest typecheck:VERDICT command-exit 0each.node scripts/pm/dispatch-gates.mjs --commands(86 families) run locally, reconciled with--ran:86 derived, 84 run, 2 NOT-MEASURED, 0 UNRUN. The two exit 3 (prerequisite: a full workspace build):check:dual-build-cjs-loads,check:type-check-debt. Every other family exit 0.@objectstack/spectypecheck (queue-timeout), the full@objectstack/metadata-protocol,@objectstack/objectql,@objectstack/restsuites on the merged head,pnpm lint. CI runs them on this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn